import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

/**
 * HttpClient线程类，用于到Git和Sonar网上获取数据
 ******************************************
 * @author HuangFeng  [2017年7月5日 下午12:57:39]
 * @version 1.0
 ******************************************
 */
public class HttpClientThread extends Thread {

	private Map<String, CloseableHttpClient> httpclientMap = new HashMap<String, CloseableHttpClient>();
	private String indexUrl = "http://bm.scs.gov.cn/pp/gkweb/uaa/personlogin?examkey=20180011";
	private String imageUrl = "http://bm.scs.gov.cn/pp/gkweb/captcha/img/img_captcha_";
	private String loginUrl = "http://bm.scs.gov.cn/pp/gkweb/api/person/idandmobile/login";
	private String collectUrl = "http://bm.scs.gov.cn/pp/gkweb/core-web-app/api/person/collection/collectPosition";
	private String getCollectUrl = "http://bm.scs.gov.cn/pp/gkweb/core-web-app/api/person/collection/getCollection";
	private String cancelCollectUrl = "http://bm.scs.gov.cn/pp/gkweb/core-web-app/api/person/collection/cancelCollection";
	private String username = "E70397C8D7506B11CD8485A05737C5BF4172B55BC890EBED3EF1829393D0E8240154B66A0910D56EBBC812ABB05239B98F1798F9499C7556";
	private String password = "BCD329B93745174FFB1398BC6ED0D923B29C6CC3E86BD661";
	private String sessionId = "";
	private String _csrf = "";
	private String captchaWord = "";
	private List<ZhiWei> zhiWeis;
	private List<Result> results;
	private Dao dao ;
	private boolean flag_exit = false;
	
	public static void main(String[] args) {
		HttpClientThread httpClientThread = new HttpClientThread();
		httpClientThread.setFlag_exit(true);
		httpClientThread.start();
	}

	/**构造方法
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午1:55:34]
	 * @version 1.0
	 ******************************************
	 */
	public HttpClientThread() {
		login();
		dao = new Dao();
		results = new ArrayList<Result>();
	}

	@Override
	public void run() {
		zhiWeis = dao.queryAllZhiWei();
		while(flag_exit){
			for (ZhiWei zhiWei : zhiWeis) {
				collectPosition(zhiWei.getHb11Id());
				String json = getCollectPosition();
				analyticParameter(json);
				cancelCollection(zhiWei.getHb11Id());
			}
			dao.deleteResult();
			dao.saveResult(results);
			dao.updatePassNum();
			results = new ArrayList<Result>();
		}
	}

	/**
	 ******************************************
	 * @author HuangFeng [2017年11月6日 下午5:02:11]
	 * @version 1.0
	 ******************************************
	 * @param json
	 */
	private void analyticParameter(String json) {
		Result result = new Result();
		try {
			int startIndex = json.indexOf("ahb110");
			String zhiweihao = json.substring(startIndex+9, startIndex+21);
			startIndex = json.indexOf("ahd01b");
			String bumenhao = json.substring(startIndex+9, startIndex+15);
			startIndex = json.indexOf("passnum");
			String passnum = json.substring(startIndex+9, json.indexOf(",",startIndex));
			startIndex = json.indexOf("waitnum");
			String waitnum = json.substring(startIndex+9, json.indexOf("}",startIndex));
			result.setBumenhao(bumenhao);
			result.setZhiweihao(zhiweihao);
			result.setPassnum(passnum);
			result.setWaitnum(waitnum);
			results.add(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("static-access")
	private void login(){
		build("gov",indexUrl);
		doGetImage("gov", imageUrl+sessionId+"?random="+Math.random());
		try {
			Thread.currentThread().sleep(40000);
			File file = new File("/root/yzm.txt");
			if (file.isFile() && file.exists()) {
				InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "utf-8");
				BufferedReader br = new BufferedReader(isr);
				String lineTxt = null;
				while ((lineTxt = br.readLine()) != null) {
					captchaWord = lineTxt;
				}
				br.close();
			} else {
				System.out.println("文件不存在!");
			}
		} catch (Exception e) {
			System.out.println("文件读取错误!");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("captchaId", "img_captcha_"+sessionId);
		params.put("captchaWord", captchaWord);
		params.put("_csrf", _csrf);
		params.put("username", username);
		params.put("password", password);
		doPost("gov", loginUrl, params);
	}
	
	private void collectPosition(String hb11Id){
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("hb11Id", hb11Id);
		doPost("gov", collectUrl, params);
	}
	
	private void cancelCollection(String hb11Id){
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("hb11Id", hb11Id);
		doPost("gov", cancelCollectUrl, params);
	}
	
	private String getCollectPosition(){
		return doGet("gov", getCollectUrl, null);
	}
	
	/**
	 * 创建HttpClient对象，信任所有签名
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午1:02:10]
	 * @version 1.0
	 ******************************************
	 * @return HttpClient对象
	 */
	private CloseableHttpClient createSSLClientDefault(CookieStore cookieStore) {
		SSLContext sslContext;
		try {
			sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
				// 信任所有
				public boolean isTrusted(X509Certificate[] xcs, String string) {
					return true;
				}
			}).build();
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
			return HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultCookieStore(cookieStore).build();
		} catch (KeyStoreException ex) {
			ex.printStackTrace();
		} catch (NoSuchAlgorithmException ex) {
			ex.printStackTrace();
		} catch (KeyManagementException ex) {
			ex.printStackTrace();
		}
		return HttpClients.createDefault();
	}

	/**
	 * 构建httpclient
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午1:10:02]
	 * @version 1.0
	 ******************************************
	 * @param name 名称
	 * @param url 链接
	 * @return 对象
	 */
	private String build( String name , String url) {
		BasicCookieStore cookieStore = new BasicCookieStore();
		CloseableHttpClient httpClient = createSSLClientDefault(cookieStore);
		HttpGet get = new HttpGet(url);
		CloseableHttpResponse response = null;
		String result = "";
		try {
			response = httpClient.execute(get);
			HttpEntity entity = response.getEntity();
			result = EntityUtils.toString(entity, "UTF-8");
			httpclientMap.put(name, httpClient);
			List<Cookie> cookies = cookieStore.getCookies();
            for (int i = 0; i < cookies.size(); i++) {
	            //这里是读取Cookie['JSPSESSID']的值存在静态变量中，保证每次都是同一个值
	            if ("SESSION".equals(cookies.get(i).getName())) {
	                sessionId = cookies.get(i).getValue();
	            }
	            if ("XSRF-TOKEN".equals(cookies.get(i).getName())) {
	            	_csrf = cookies.get(i).getValue();
	            }
            }
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (null != response) {
				try {
					EntityUtils.consume(response.getEntity());
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
		return result;
	}

	/**
	 * Post请求
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午1:10:47]
	 * @version 1.0
	 ******************************************
	 * @param name HttpClient对象名
	 * @param url 链接
	 * @param params 请求参数
	 * @return 结果
	 */
	private String doPost(String name ,  String url, Map<String, Object> params) {
		HttpPost post = new HttpPost(url);
		CloseableHttpResponse response = null;
		if (null != params && !params.isEmpty()) {
			List<NameValuePair> nvpList = new ArrayList<NameValuePair>();
			for (Map.Entry<String, Object> entry : params.entrySet()) {
				NameValuePair nvp = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
				nvpList.add(nvp);
			}
			post.setEntity(new UrlEncodedFormEntity(nvpList, Charset.forName("UTF-8")));
		}
		String result = "";
		try {
			response = httpclientMap.get(name).execute(post);
			HttpEntity entity = response.getEntity();
			result = EntityUtils.toString(entity, "UTF-8");
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (null != response) {
				try {
					EntityUtils.consume(response.getEntity());
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
		return result;
	}
	
	/**
	 * Get请求
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午1:10:47]
	 * @version 1.0
	 ******************************************
	 * @param name HttpClient对象名
	 * @param url 链接
	 * @param params 请求参数
	 * @return 结果
	 */
	private String doGet(String name , String url, Map<String, Object> params) {
		StringBuilder sb = new StringBuilder("");
		if (null != params && !params.isEmpty()) {
			int i = 0;
			for (String key : params.keySet()) {
				if (i == 0) {
					sb.append("?");
				} else {
					sb.append("&");
				}
				sb.append(key).append("=").append(params.get(key));
				i++;
			}
		}
		CloseableHttpResponse response = null;
		HttpGet get = new HttpGet(url + sb.toString());
		String result = "";
		try {
			response = httpclientMap.get(name).execute(get);
			if (response.getStatusLine().getStatusCode() == 200) {
				HttpEntity entity = response.getEntity();
				if (null != entity) {
					result = EntityUtils.toString(entity, "UTF-8");
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (null != response) {
				try {
					EntityUtils.consume(response.getEntity());
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
		return result;
	}
	
	/**
	 * Get请求
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午1:10:47]
	 * @version 1.0
	 ******************************************
	 * @param name HttpClient对象名
	 * @param url 链接
	 * @param params 请求参数
	 * @return 结果
	 */
	private void doGetImage(String name , String url) {
		CloseableHttpResponse response = null;
		HttpGet get = new HttpGet(url);
		try {
			response = httpclientMap.get(name).execute(get);
			if (response.getStatusLine().getStatusCode() == 200) {
				HttpEntity entity = response.getEntity();
				if (null != entity) {
					byte[] data = EntityUtils.toByteArray(entity);  
	                //图片存入磁盘  
	                FileOutputStream fos = new FileOutputStream("/root/yzm.jpg");  
	                fos.write(data);  
	                fos.close();  
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (null != response) {
				try {
					EntityUtils.consume(response.getEntity());
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
	}

	public void setFlag_exit(boolean b) {
		flag_exit = b;
	}

}
